#ifndef TCPC_EVENT_H_
#define TCPC_EVENT_H_

#include "common.h"

enum pd_event_type {
    PD_EVT_PD_MSG = 0,	/* either ctrl msg or data msg */
    PD_EVT_CTRL_MSG,
    PD_EVT_DATA_MSG,
#ifdef CONFIG_USB_PD_REV30
    PD_EVT_EXT_MSG,
#endif /* CONFIG_USB_PD_REV30 */
    PD_EVT_PD_MSG_END,
    PD_EVT_DPM_MSG = PD_EVT_PD_MSG_END,
    PD_EVT_HW_MSG,
    PD_EVT_PE_MSG,
    PD_EVT_TIMER_MSG,
    PD_EVT_TCP_MSG,
};

enum pd_msg_type {
/* Control Message type */
    /* 0 Reserved */
    PD_CTRL_GOOD_CRC = 1,
    PD_CTRL_GOTO_MIN = 2,
    PD_CTRL_ACCEPT = 3,
    PD_CTRL_REJECT = 4,
    PD_CTRL_PING = 5,
    PD_CTRL_PS_RDY = 6,
    PD_CTRL_GET_SOURCE_CAP = 7,
    PD_CTRL_GET_SINK_CAP = 8,
    PD_CTRL_DR_SWAP = 9,
    PD_CTRL_PR_SWAP = 10,
    PD_CTRL_VCONN_SWAP = 11,
    PD_CTRL_WAIT = 12,
    PD_CTRL_SOFT_RESET = 13,
    /* 14-15 Reserved */
    PD_CTRL_PD30_START = 0x10 + 0,
#if CONFIG_USB_PD_REV30
    PD_CTRL_NOT_SUPPORTED = 0x10 + 0,
    PD_CTRL_GET_SOURCE_CAP_EXT = 0x10 + 1,
    PD_CTRL_GET_STATUS = 0x10 + 2,
    PD_CTRL_FR_SWAP = 0x10 + 3,
    PD_CTRL_GET_PPS_STATUS = 0x10 + 4,
    PD_CTRL_GET_COUNTRY_CODE = 0x10 + 5,
    PD_CTRL_GET_SINK_CAP_EXT = 0x10 + 6,
    PD_CTRL_GET_REVISION = 0x10 + 8,
#endif	/* CONFIG_USB_PD_REV30 */
    /* 22-31 Reserved */
    PD_CTRL_MSG_NR,
/* Data message type */
    /* 0 Reserved */
    PD_DATA_SOURCE_CAP = 1,
    PD_DATA_REQUEST = 2,
    PD_DATA_BIST = 3,
    PD_DATA_SINK_CAP = 4,
    PD_DATA_PD30_START = 5,
#if CONFIG_USB_PD_REV30
    PD_DATA_BAT_STATUS = 5,
    PD_DATA_ALERT = 6,
    PD_DATA_GET_COUNTRY_INFO = 7,
    PD_DATA_REVISION = 12,
#endif	/* CONFIG_USB_PD_REV30 */
    /* 8-11 and 13-14 Reserved Reserved */
    PD_DATA_VENDOR_DEF = 15,
    PD_DATA_MSG_NR,
#if CONFIG_USB_PD_REV30
/* Extended message type */
    /* 0 Reserved */
    PD_EXT_SOURCE_CAP_EXT = 1,
    PD_EXT_STATUS = 2,
    PD_EXT_GET_BAT_CAP = 3,
    PD_EXT_GET_BAT_STATUS = 4,
    PD_EXT_BAT_CAP = 5,
    PD_EXT_GET_MFR_INFO = 6,
    PD_EXT_MFR_INFO = 7,
    PD_EXT_SEC_REQUEST = 8,
    PD_EXT_SEC_RESPONSE = 9,
    PD_EXT_FW_UPDATE_REQUEST = 10,
    PD_EXT_FW_UPDATE_RESPONSE = 11,
    PD_EXT_PPS_STATUS = 12,
    PD_EXT_COUNTRY_INFO = 13,
    PD_EXT_COUNTRY_CODES = 14,
    PD_EXT_SINK_CAP_EXT = 15,
    /* 15 Reserved */
    PD_EXT_MSG_NR,
#endif	/* CONFIG_USB_PD_REV30 */
/* HW Message type */
    PD_HW_CC_DETACHED = 0,
    PD_HW_CC_ATTACHED,
    PD_HW_RECV_HARD_RESET,
    PD_HW_VBUS_PRESENT,
    PD_HW_VBUS_ABSENT,
    PD_HW_VBUS_SAFE0V,
    PD_HW_VBUS_STABLE,
    PD_HW_TX_FAILED,	/* no good crc */
    PD_HW_TX_DISCARD,	/* discard msg */
    PD_HW_RETRY_VDM,	/* discard vdm msg (retry) */
    PD_HW_SINK_TX_CHANGE,
#if CONFIG_USB_PD_RETRY_CRC_DISCARD
    PD_HW_TX_RETRANSMIT,
#endif	/* CONFIG_USB_PD_RETRY_CRC_DISCARD */
    PD_HW_MSG_NR,
/* PE Message type*/
    PD_PE_RESET_PRL_COMPLETED = 0,
    PD_PE_POWER_ROLE_AT_DEFAULT,
    PD_PE_HARD_RESET_COMPLETED,
    PD_PE_IDLE,
    PD_PE_VDM_RESET,
    PD_PE_VDM_NOT_SUPPORT,
    PD_PE_MSG_NR,
/* DPM Message type */
    PD_DPM_NOTIFIED = 0,
    PD_DPM_ACK = PD_DPM_NOTIFIED,
    PD_DPM_NAK,
    PD_DPM_NOT_SUPPORT,
    PD_DPM_CABLE_NOT_SUPPORT,
    PD_DPM_MSG_NR,
};

enum pd_tcp_sec_msg_type {
    PD_TCP_FROM_TCPM = 0,
    PD_TCP_FROM_PE = 1,
};
enum pd_dpm_nak_type {
    PD_DPM_NAK_REJECT = 0,
    PD_DPM_NAK_WAIT = 1,
};

enum pd_tx_transmit_state {
    PD_TX_STATE_GOOD_CRC = 0,
    PD_TX_STATE_NO_GOOD_CRC,
    PD_TX_STATE_DISCARD,
    PD_TX_STATE_HARD_RESET,
    PD_TX_STATE_NO_RESPONSE,
    PD_TX_STATE_WAIT,
    PD_TX_STATE_WAIT_CRC_VDM = PD_TX_STATE_WAIT,
    PD_TX_STATE_WAIT_CRC_PD,
    PD_TX_STATE_WAIT_HARD_RESET,
};

static inline bool pd_event_msg_match(struct pd_event *pd_event,
					uint8_t type, uint8_t msg)
{
	return pd_event->event_type == type && pd_event->msg == msg;
}

static inline bool pd_event_ctrl_msg_match(
		struct pd_event *pd_event, uint8_t msg)
{
	return pd_event_msg_match(pd_event, PD_EVT_CTRL_MSG, msg);
}

static inline bool pd_event_data_msg_match(
		struct pd_event *pd_event, uint8_t msg)
{
	return pd_event_msg_match(pd_event, PD_EVT_DATA_MSG, msg);
}

static inline bool pd_event_hw_msg_match(struct pd_event *pd_event, uint8_t msg)
{
	return pd_event_msg_match(pd_event, PD_EVT_HW_MSG, msg);
}

static inline bool pd_event_pe_msg_match(struct pd_event *pd_event, uint8_t msg)
{
	return pd_event_msg_match(pd_event, PD_EVT_PE_MSG, msg);
}

static inline bool pd_event_timer_msg_match(
			struct pd_event *pd_event, uint8_t msg)
{
	return pd_event_msg_match(pd_event, PD_EVT_TIMER_MSG, msg);
}

#if CONFIG_USB_PD_REV30

static inline bool pd_event_ext_msg_match(
	struct pd_event *pd_event, uint8_t msg)
{
	return pd_event_msg_match(pd_event, PD_EVT_EXT_MSG, msg);
}

#endif	/* CONFIG_USB_PD_REV30 */

bool vdm_put_pe_event(struct sgm41620_tcpc *tcpc_dev, uint8_t pe_event);
bool vdm_put_dpm_discover_cable_id_event(struct pd_port *pd_port);
bool pd_put_pd_msg_event(struct sgm41620_tcpc *tcpc_dev, struct pd_msg *pd_msg);
bool pd_put_event(struct sgm41620_tcpc *tcpc_dev, const struct pd_event *pd_event, bool from_port_partner);
bool pd_get_event(struct sgm41620_tcpc *tcpc_dev, struct pd_event *pd_event);;
bool pd_put_pe_event(struct pd_port *pd_port, uint8_t pe_event);
bool pd_put_dpm_notify_event(struct pd_port *pd_port, uint8_t notify);
bool pd_put_dpm_ack_event(struct pd_port *pd_port);
bool pd_put_dpm_nak_event(struct pd_port *pd_port, uint8_t notify);
bool pd_put_tcp_pd_event(struct pd_port *pd_port, uint8_t event, uint8_t from);
bool pd_put_dpm_event(struct pd_port *pd_port, uint8_t msg);
bool pd_put_tcp_vdm_event(struct pd_port *pd_port, uint8_t event);
bool pd_put_sink_tx_event(struct sgm41620_tcpc *tcpc, uint8_t cc_res);
bool pd_put_hw_event(struct sgm41620_tcpc *tcpc_dev, uint8_t hw_event);
bool vdm_put_hw_event(struct sgm41620_tcpc *tcpc_dev, uint8_t hw_event);
bool pd_put_vdm_event(struct sgm41620_tcpc *tcpc_dev,struct pd_event *pd_event,bool from_port_partner);
bool pd_get_vdm_event(struct sgm41620_tcpc *tcpc_dev, struct pd_event *pd_event);
//bool pe_is_valid_pd_msg_id(struct pd_port *pd_port,struct pd_event *pd_event, struct pd_msg *pd_msg);
//bool pe_is_valid_pd_msg_role(struct pd_port *pd_port,struct pd_event *pd_event, struct pd_msg *pd_msg);
//void pe_translate_pd_msg_event(struct pd_port *pd_port,struct pd_event *pd_event, struct pd_msg *pd_msg);
void __pd_free_event(struct sgm41620_tcpc *tcpc_dev, struct pd_event *pd_event);
bool pd_is_msg_empty(struct sgm41620_tcpc *tcpc_dev);
void pd_put_sent_hard_reset_event(struct sgm41620_tcpc *tcpc);
bool pd_get_deferred_tcp_event(
	struct sgm41620_tcpc *tcpc, struct tcp_dpm_event *tcp_event);
bool pd_put_deferred_tcp_event(
	struct sgm41620_tcpc *tcpc, const struct tcp_dpm_event *tcp_event);
bool pd_check_ctrl_msg_event(struct pd_port *pd_port, uint8_t msg);

void pd_postpone_vdm_event_timeout(struct sgm41620_tcpc *tcpc_dev);

void pd_put_vbus_changed_event(struct sgm41620_tcpc *tcpc);
void pd_put_vbus_safe0v_event(struct sgm41620_tcpc *tcpc, bool safe0v);
void pd_put_vbus_stable_event(struct sgm41620_tcpc *tcpc);

bool real_pd_put_cc_attached_event(struct sgm41620_tcpc *tcpc, uint8_t type);
bool pd_put_cc_attached_event(struct sgm41620_tcpc *tcpc, uint8_t type);
void pd_put_cc_detached_event(struct sgm41620_tcpc *tcpc);
extern void pd_event_buf_reset(struct sgm41620_tcpc *tcpc);

void pd_put_recv_hard_reset_event(struct sgm41620_tcpc *tcpc);

struct pd_msg *__pd_alloc_msg(struct sgm41620_tcpc *tcpc_dev);
void __pd_free_msg(struct sgm41620_tcpc *tcpc_dev, struct pd_msg *pd_msg);
void tcpc_event_thread_wake_up(struct sgm41620_tcpc *tcpc_dev);
int tcpci_event_init_work(struct sgm41620_tcpc *tcpc_dev);
void pd_notify_pe_snk_explicit_contract(struct pd_port *pd_port);
void pd_notify_pe_src_explicit_contract(struct pd_port *pd_port);
void pd_notify_pe_wait_vbus_once(struct pd_port *pd_port, int wait_evt);


#endif /* TCPC_EVENT_H_*/

